﻿using Sgr.DataCategories.Application.Queries;
using Sgr.DataCategories.Application.ViewModels;
using Sgr.DataCategories.Stores;
using System.Collections.Generic;

namespace Sgr.DataCategories.Services
{
    /// <summary>
    /// 行政区划管理实现类
    /// </summary>
    public class AdmDivManagement : IAdmDivManagement
    {
        // 本地行政区划存储
        private readonly IAdmDivStore _admDivStore;

        // 行政区划查询服务
        private readonly IAdministrativeDivisionQueries _administrativeDivisionQueries;

        /// <summary>
        /// 构造函数，注入依赖
        /// </summary>
        /// <param name="admDivStore">本地行政区划存储</param>
        /// <param name="administrativeDivisionQueries">行政区划查询服务</param>
        public AdmDivManagement(IAdmDivStore admDivStore, IAdministrativeDivisionQueries administrativeDivisionQueries)
        {
            _admDivStore = admDivStore ?? throw new ArgumentNullException(nameof(admDivStore));
            _administrativeDivisionQueries = administrativeDivisionQueries ?? throw new ArgumentNullException(nameof(administrativeDivisionQueries));
        }

        /// <summary>
        /// 异步获取所有的行政区划列表
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<IEnumerable<AdmDiv>> GetAllAsync(CancellationToken cancellationToken = default)
        {
            // 从本地缓存获取或加载行政区划数据
            return await _admDivStore.GetOrAddAsync(LoadDataAsync, cancellationToken);
        }

        /// <summary>
        /// 异步获取行政区划列表
        /// </summary>
        /// <param name="admDivKey">行政区划关键字（可选，默认为空字符串）</param>
        /// <param name="includeSubNodes">是否包含子孙节点</param>
        /// <param name="cancellationToken">取消操作的标记（可选）</param>
        /// <returns>行政区划集合</returns>
        public async Task<IEnumerable<AdmDiv>> GetListAsync(
            string admDivKey = "",
            bool includeSubNodes = false,
            CancellationToken cancellationToken = default)
        {
            // 从本地缓存获取或加载行政区划数据
            IEnumerable<AdmDiv> list = await _admDivStore.GetOrAddAsync(LoadDataAsync, cancellationToken);

            if (string.IsNullOrEmpty(admDivKey))
                return Array.Empty<AdmDiv>();
            else
            {
                var items = list.Where(x => x.Pid == admDivKey && x.IsActive);
                //如果PID等于0，且有且仅有一条记录（中国），那么返回中国下面的省
                if (admDivKey == "0" && items.Count() == 1)
                {
                    string pid = items.First().Id;
                    items = list.Where(x => x.Pid == pid && x.IsActive);
                }

                if(!includeSubNodes)
                    return items;

                //递归加载所有的子孙节点
                var result = new List<AdmDiv>(items);

                void AddChildren(IEnumerable<AdmDiv> parents)
                {
                    foreach (var parent in parents)
                    {
                        var children = list.Where(x => x.Pid == parent.Id && x.IsActive).ToList();
                        if (children.Count > 0)
                        {
                            result.AddRange(children);
                            AddChildren(children);
                        }
                    }
                }

                AddChildren(items);
                return result;
            }
                
        }

        /// <summary>
        /// 异步刷新所有行政区划缓存
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        public async Task RefreshAsync(CancellationToken cancellationToken = default)
        {
            // 重新加载数据并刷新本地缓存
            IEnumerable<AdmDiv> list = await LoadDataAsync(cancellationToken);
            await _admDivStore.RefreshAsync(list, cancellationToken);
        }

        /// <summary>
        /// 异步加载所有行政区划数据
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>行政区划集合</returns>
        private async Task<IEnumerable<AdmDiv>> LoadDataAsync(CancellationToken cancellationToken)
        {
            // 查询所有行政区划视图模型
            IEnumerable<OutAdministrativeDivisionViewModel> admDivs = await _administrativeDivisionQueries.GetNormalListAsync(cancellationToken).ConfigureAwait(false);

            var admDivList = admDivs.ToList();
            //var idSet = new HashSet<string>(admDivList.Select(x => x.Id.ToString()));

            // 统计每个节点的子节点情况
            var hasChildMap = admDivList
                .GroupBy(x => x.ParentId?.ToString() ?? "0")
                .ToDictionary(g => g.Key, g => g.Count());

            // 构建 AdmDiv 列表
            var result = admDivList.Select(x => new AdmDiv
            {
                Id = x.Id.ToString(),
                Pid = x.ParentId?.ToString() ?? "0",
                Code = x.Code,
                Name = x.Name,
                IsActive = x.State == Sgr.Domain.Entities.EntityStates.Normal,
                HasChild = hasChildMap.ContainsKey(x.Id.ToString())
            });

            return result;
        }
    }
}